using System;
using System.Data;
using System.Data.SqlClient;
using System.Data.SqlTypes;
using Microsoft.SqlServer.Server;


//[Serializable]
[Microsoft.SqlServer.Server.SqlUserDefinedAggregate(Format.UserDefined, MaxByteSize=256)]
public struct VectorAvg : IBinarySerialize
{
    private double[] sum;
    private int count;

    public void Init()
    {
        sum = null;
        count = 0;
    }

    public void Accumulate(SqlBinary Value)
    {
        double[] vec = Elte.SqlSpIdx.Converters.VectorConverter.ToArray(Value);

        if (count == 0)
            sum = new double[vec.Length];

        for (int k = 0; k < vec.Length; k++)
            sum[k] += vec[k];
        
        count++;
    }

    public void Merge(VectorAvg Group)
    {
        if (count == 0)
            sum = new double[Group.sum.Length];

        for (int k = 0; k < Group.sum.Length; k++)
            sum[k] += Group.sum[k];

        count += Group.count;
    }

    public SqlBinary Terminate()
    {
        for (int k = 0; k < sum.Length; k++)
            sum[k] /= count;

        return new SqlBinary(Elte.SqlSpIdx.Converters.VectorConverter.ToBinary(sum));
    }


    #region IBinarySerialize Members

    public void Read(System.IO.BinaryReader r)
    {
        count = r.ReadInt32();
        int length = r.ReadInt32();
        sum = Elte.SqlSpIdx.Converters.VectorConverter.ToArray(r.ReadBytes(length * sizeof(double) + sizeof(int) + sizeof(int)));
    }

    public void Write(System.IO.BinaryWriter w)
    {
        w.Write(count);
        w.Write(sum.Length);
        w.Write(Elte.SqlSpIdx.Converters.VectorConverter.ToBinary(sum));
    }

    #endregion
}
